﻿using System.Collections;
using System.Collections.Generic;
using Cms.Domain;
using Cms.Domain.Comparers;
using Cms.Domain.RepositoryInterfaces;
using NHibernate;
using NHibernate.Criterion;
using NHibernate.Transform;

namespace Cms.Data
{
    public class MediaRepository : BaseRepository, IMediaRepository
    {
        public MediaRepository()
        {
        }

        public MediaRepository(ISession session)
            : base(session)
        {
        }

        #region IMediaRepository Members

        public MediaFolder GetMediaFolder(int id)
        {
            return Session.Get<MediaFolder>(id);
        }
        
        public virtual IList<MediaFile> GetMediaFiles(int siteID, int mediaFolderID)
        {
            return Session.CreateCriteria(typeof(MediaFile))
                    .Add(Restrictions.Eq("Site.ID", siteID))
                    .Add(mediaFolderID > 0 ? Restrictions.Eq("Folder.ID", mediaFolderID) : Restrictions.IsNull("Folder.ID"))
                    .AddOrder(new NHibernate.Criterion.Order("Name", true))
                    .SetCacheable(true)
                    .List<MediaFile>();
        }
        
        public MediaFile GetMediaFile(int id)
        {
            return Session.Get<MediaFile>(id);
        }

        public MediaFile GetMediaFileFromFrontEnd(int id)
        {
            var mediaFile = Session.CreateQuery("from MediaFile mf where mf.ID = " + id).SetCacheable(true);
            string hql = "from MediaFile mf left join fetch mf.RequiredUserGroups where mf.ID = " + id;
            var requiredUserGroups = Session.CreateQuery(hql).SetCacheable(true);
            hql = "from MediaFile mf left join fetch mf.DeselectedUserGroups where mf.ID = " + id;
            var deselectedUserGroups = Session.CreateQuery(hql).SetCacheable(true);
            hql = "from MediaFile mf left join fetch mf.Categories where mf.ID = " + id;
            var categories = Session.CreateQuery(hql).SetCacheable(true);
            hql = "from MediaFile mf left join fetch mf.LocalizedProperties where mf.ID = " + id;
            var properties = Session.CreateQuery(hql).SetCacheable(true);
            IList result = Session.CreateMultiQuery()
                                        .Add(mediaFile)
                                        .Add(requiredUserGroups)
                                        .Add(deselectedUserGroups)
                                        .Add(categories)
                                        .Add(properties)
                                        .SetCacheable(true)
                                        .List();
            var mediaFiles = result[0] as ArrayList;
            if (mediaFiles != null && mediaFiles.Count > 0)
            {
                return (MediaFile)mediaFiles[0];
            }
            return null;
        }

        public void SaveMediaFile(MediaFile file)
        {
            SaveEntity(file, "MediaRepository.SaveMediaFile");
        }
        
        public void DeleteMediaFile(int id)
        {
            DeleteHql("from MediaFile where Id = " + id, "MediaRepository.DeleteMediaFile");
        }
        
        public void SaveMediaFolder(MediaFolder folder)
        {
            SaveEntity(folder, "MediaRepository.SaveMediaFolder");
        }

        public void DeleteCategory(Category category)
        {
            DeleteEntity(category, "MediaRepository.DeleteCategory");
        }

        public Category GetCategory(int id)
        {
            return Session.Get<Category>(id);
        }

        public void SaveCategory(Category category)
        {
            SaveEntity(category, "MediaRepository.SaveCategory");
        }
        
        public bool CategoryExists(string name, int id, int siteID)
        {
            string hql = "from MediaCategory mc where mc.Name = :name and mc.Site.ID = " + siteID;
            if (id > 0)
                hql += " and mc.ID <> " + id;
            IList<Category> categories = Session.CreateQuery(hql)
                .SetString("name", name)
                .List<Category>();
            return categories.Count > 0;
        }
        
        #endregion
    }
}